#ifndef INFINITY_MANAGED_GAME_OBJECT_H
#	define INFINITY_MANAGED_GAME_OBJECT_H

namespace infinity {

class ManagedGameObjectBase
{
public : //! @name Types definitions
	//! @{
	enum State
	{
		State_Invalid = -1,
		State_Initializing,
		State_Initialized,
		State_InitializationFailed,
		State_Terminating,
		State_Terminated
	};
	//! @}
};

template< class Manager >
class ManagedGameObject
:	public ManagedGameObjectBase
{
public : //! @name Commands
	//! @{
	virtual void renderDebug();
	//! @}

public : //! @name State
	//! @{
	bool isReadyForSimulation() const ;
	bool isReadyForMedia() const ;
	bool needsSimulationInitialization() const ;
	bool needsMediaInitialization() const ;
	bool needsSimulationTermination() const ;
	bool needsMediaTermination() const ;
	//! @}

protected : //! @name Internal Construction & Destruction
	//! @{
	ManagedGameObject();
	virtual ~ManagedGameObject();
	//! @}

protected : //! @name Callbacks
	//! @{
	virtual State onInitializeSimulation();
	virtual void onUpdateSimulation(dw::float32 deltaT);
	virtual State onTerminateSimulation();
	
	virtual State onInitializeMedia();
	virtual void onUpdateMedia(dw::float32 deltaT);
	virtual State onTerminateMedia();
	//! @}

private : //! @name Copy protection
	//! @{
	ManagedGameObject(const ManagedGameObject& ref);
	ManagedGameObject& operator = (const ManagedGameObject& ref);
	//! @}

private : //! @name Internal commands
	//! @{
	friend typename Manager;

	void initializeSimulation();
	void updateSimulation(dw::float32 deltaT);
	void terminateSimulation();

	void initializeMedia();
	void updateMedia(dw::float32 deltaT);
	void terminateMedia();
	//! @}
	
private : //! @name Data
	//! @{
	State m_simulationState;
	State m_mediaState;
	//! @}
};

} // namespace infinity

#include "managedgameobject.inl"

#endif //!INFINITY_MANAGED_GAME_OBJECT_H
